package com.zapi.lottery.controller;

import com.zapi.lottery.service.LotteryWinningNumberService;
import com.zapi.lottery.entity.LotteryPrize;
import com.zapi.lottery.entity.LotteryRecord;
import com.zapi.lottery.entity.LotterySetting;
import com.zapi.lottery.service.LotteryPrizeService;
import com.zapi.lottery.service.LotteryRecordService;
import com.zapi.lottery.service.LotterySettingService;
import com.zapi.lottery.utils.LotteryDataUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import com.zapi.lottery.entity.LotteryWinningNumber;

/**
 * 抽奖游戏控制器
 * 提供抽奖核心业务逻辑接口
 * @author: zhonglz
 * @DATE: 2024-06-09
 */
@RestController
@RequestMapping("/lottery/game")
public class LotteryGameController {
    @Autowired
    private LotteryPrizeService lotteryPrizeService;
    @Autowired
    private LotterySettingService lotterySettingService;
    @Autowired
    private LotteryRecordService lotteryRecordService;

    // 内存中存储当前抽奖状态和中奖记录
    private static final Map<String, Object> gameState = new ConcurrentHashMap<>();
    private static final Map<String, List<String>> awardWinners = new ConcurrentHashMap<>();

    @Autowired
    private LotteryDataUtils lotteryDataUtils;

    @Autowired
    private LotteryWinningNumberService lotteryWinningNumberService;

    /**
     * 开始抽奖
     * @param request 抽奖请求
     * @return 抽奖结果
     */
    @PostMapping("/start")
    public Map<String, Object> startLottery(@RequestBody LotteryStartRequest request) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            // 获取当前奖项设置
            LotterySetting setting = lotterySettingService.getById(request.getSettingId());
            if (setting == null || setting.getStatus() != 1) {
                result.put("success", false);
                result.put("message", "奖项设置不存在或已关闭");
                return result;
            }

            // 检查中奖人数限制
            String awardKey = getAwardKeyByCode(setting.getAwardCode());
            List<String> winners = awardWinners.getOrDefault(awardKey, new ArrayList<>());
            if (winners.size() >= setting.getTotalWinners()) {
                result.put("success", false);
                result.put("message", "本奖项已达中奖人数上限");
                return result;
            }

            // 获取抽奖范围设置
            List<LotteryPrize> prizes = lotteryPrizeService.list();
            if (prizes.isEmpty()) {
                result.put("success", false);
                result.put("message", "未配置抽奖范围");
                return result;
            }
            LotteryPrize prize = prizes.get(0);
            int minNumber = Integer.parseInt(prize.getMinNumber());
            int maxNumber = Integer.parseInt(prize.getMaxNumber());

            // 获取该奖项的预定义中奖号码
            List<LotteryWinningNumber> winningNumbers = lotteryWinningNumberService.getBySettingIdAndStatus(request.getSettingId(), 1);
            
            String luckyNumberStr;
            String lotteryType = "random"; // 记录抽奖类型：configured 或 random
            
            if (!winningNumbers.isEmpty()) {
                // 优先使用配置的中奖号码
                List<String> availableConfiguredNumbers = new ArrayList<>();
                for (LotteryWinningNumber winningNumber : winningNumbers) {
                    if (!winners.contains(winningNumber.getWinningNumber())) {
                        availableConfiguredNumbers.add(winningNumber.getWinningNumber());
                    }
                }
                
                if (!availableConfiguredNumbers.isEmpty()) {
                    // 从配置号码中随机选择一个
                    luckyNumberStr = availableConfiguredNumbers.get(new java.util.Random().nextInt(availableConfiguredNumbers.size()));
                    lotteryType = "configured";
                } else {
                    // 配置号码已用完，使用随机号码
                    luckyNumberStr = generateRandomNumberAvoidingWinners(minNumber, maxNumber, winners);
                    lotteryType = "random";
                }
            } else {
                // 没有配置中奖号码，直接随机抽取
                luckyNumberStr = generateRandomNumberAvoidingWinners(minNumber, maxNumber, winners);
                lotteryType = "random";
            }
            
            // 添加到中奖记录
            winners.add(luckyNumberStr);
            awardWinners.put(awardKey, winners);

            // 保存抽奖记录到数据库
            LotteryRecord record = new LotteryRecord();
            record.setUserId(request.getUserId());
            record.setPrizeId(request.getSettingId());
            record.setLotteryNumber(luckyNumberStr);
            record.setStatus(1);
            lotteryRecordService.save(record);

            result.put("success", true);
            result.put("luckyNumber", luckyNumberStr);
            result.put("awardLevel", setting.getPrizeName());
            result.put("awardCode", setting.getAwardCode());
            result.put("lotteryType", lotteryType); // 返回抽奖类型
            result.put("message", "恭喜抽中" + setting.getPrizeName());
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "抽奖失败: " + e.getMessage());
        }
        
        return result;
    }

    /**
     * 获取中奖记录
     * @return 各奖项中奖记录
     */
    @GetMapping("/winners")
    public Map<String, Object> getWinners() {
        Map<String, Object> result = new HashMap<>();
        result.put("awardWinners", awardWinners);
        result.put("success", true);
        return result;
    }

    /**
     * 重置抽奖
     * @return 重置结果
     */
    @PostMapping("/reset")
    public Map<String, Object> resetLottery() {
        try {
            // 清空内存中的中奖记录
            awardWinners.clear();
            gameState.clear();
            
            // 可选：清空数据库中的抽奖记录
            // lotteryRecordService.remove(null);
            
            Map<String, Object> result = new HashMap<>();
            result.put("success", true);
            result.put("message", "抽奖已重置");
            return result;
        } catch (Exception e) {
            Map<String, Object> result = new HashMap<>();
            result.put("success", false);
            result.put("message", "重置失败：" + e.getMessage());
            return result;
        }
    }

    /**
     * 获取抽奖设置
     * @return 抽奖设置信息
     */
    @GetMapping("/settings")
    public Map<String, Object> getSettings() {
        Map<String, Object> result = new HashMap<>();
        
        try {
            // 获取所有抽奖设置
            List<LotteryPrize> prizes = lotteryPrizeService.list();
            List<LotterySetting> settings = lotterySettingService.list();
            
            result.put("prizes", prizes);
            result.put("settings", settings);
            result.put("success", true);
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "获取设置失败：" + e.getMessage());
        }
        
        return result;
    }

    /**
     * 保存抽奖设置
     * @param request 设置请求
     * @return 保存结果
     */
    @PostMapping("/save-settings")
    public Map<String, Object> saveSettings(@RequestBody LotterySettingsRequest request) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            // 保存抽奖范围设置
            if (request.getPrize() != null) {
                lotteryPrizeService.saveOrUpdate(request.getPrize());
            }
            
            // 保存奖项设置
            if (request.getSettings() != null) {
                for (LotterySetting setting : request.getSettings()) {
                    lotterySettingService.saveOrUpdate(setting);
                }
            }
            
            result.put("success", true);
            result.put("message", "设置保存成功");
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "保存失败：" + e.getMessage());
        }
        
        return result;
    }

    /**
     * 获取系统状态
     * @return 系统状态信息
     */
    @GetMapping("/system-status")
    public Map<String, Object> getSystemStatus() {
        return lotteryDataUtils.getSystemStatus();
    }

    /**
     * 验证系统数据完整性
     * @return 验证结果
     */
    @GetMapping("/validate-data")
    public Map<String, Object> validateData() {
        return lotteryDataUtils.validateLotteryData();
    }

    /**
     * 重置所有抽奖数据
     * @return 重置结果
     */
    @PostMapping("/reset-all")
    public Map<String, Object> resetAllData() {
        Map<String, Object> result = lotteryDataUtils.resetAllLotteryData();
        
        // 同时清空内存中的中奖记录
        if ((Boolean) result.get("success")) {
            awardWinners.clear();
            gameState.clear();
        }
        
        return result;
    }

    /**
     * 获取奖项的中奖号码配置
     * @param settingId 奖项设置ID
     * @return 中奖号码列表
     */
    @GetMapping("/winning-numbers/{settingId}")
    public List<LotteryWinningNumber> getWinningNumbers(@PathVariable Integer settingId) {
        return lotteryWinningNumberService.getBySettingId(settingId);
    }

    /**
     * 保存奖项的中奖号码配置
     * @param settingId 奖项设置ID
     * @param winningNumbers 中奖号码列表
     * @return 保存结果
     */
    @PostMapping("/winning-numbers/{settingId}")
    public Map<String, Object> saveWinningNumbers(@PathVariable Integer settingId, @RequestBody List<String> winningNumbers) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            // 验证中奖号码格式
            for (String number : winningNumbers) {
                if (!number.matches("\\d{3}")) {
                    result.put("success", false);
                    result.put("message", "中奖号码格式错误，必须是3位数字");
                    return result;
                }
            }
            
            boolean saved = lotteryWinningNumberService.batchSaveWinningNumbers(settingId, winningNumbers);
            result.put("success", saved);
            result.put("message", saved ? "中奖号码配置保存成功" : "保存失败");
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "保存失败: " + e.getMessage());
        }
        
        return result;
    }

    /**
     * 获取所有启用的中奖号码
     * @return 中奖号码列表
     */
    @GetMapping("/all-winning-numbers")
    public List<LotteryWinningNumber> getAllWinningNumbers() {
        return lotteryWinningNumberService.getAllEnabledWinningNumbers();
    }

    /**
     * 生成随机号码，避免重复
     * @param minNumber 最小号码
     * @param maxNumber 最大号码
     * @param winners 已中奖号码列表
     * @return 随机号码字符串
     */
    private String generateRandomNumberAvoidingWinners(int minNumber, int maxNumber, List<String> winners) {
        java.util.Random random = new java.util.Random();
        String luckyNumberStr;
        int maxAttempts = 1000; // 最大尝试次数，防止无限循环
        int attempts = 0;
        
        do {
            int luckyNumber = random.nextInt(maxNumber - minNumber + 1) + minNumber;
            luckyNumberStr = String.format("%03d", luckyNumber);
            attempts++;
            
            // 如果尝试次数过多，说明可能没有可用号码了
            if (attempts >= maxAttempts) {
                throw new RuntimeException("无法生成不重复的随机号码，可能所有号码都已被抽中");
            }
        } while (winners.contains(luckyNumberStr));
        
        return luckyNumberStr;
    }

    /**
     * 生成随机号码（原方法保留，用于其他场景）
     * @param minNumber 最小号码
     * @param maxNumber 最大号码
     * @return 随机号码
     */
    private int generateRandomNumber(int minNumber, int maxNumber) {
        java.util.Random random = new java.util.Random();
        return random.nextInt(maxNumber - minNumber + 1) + minNumber;
    }

    /**
     * 根据奖项标识码获取奖项Key
     * @param awardCode 奖项标识码
     * @return 奖项Key
     */
    private String getAwardKeyByCode(String awardCode) {
        if (awardCode == null) return "other";
        
        switch (awardCode.toLowerCase()) {
            case "special": return "special";
            case "first": return "first";
            case "second": return "second";
            case "third": return "third";
            case "lucky": return "lucky";
            default: return "other";
        }
    }

    private boolean isNumberAlreadyWon(String number) {
        for (List<String> winners : awardWinners.values()) {
            if (winners.contains(number)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 抽奖请求参数
     */
    public static class LotteryGameRequest {
        private Integer userId;
        private Integer prizeId;
        private Integer settingId;
        private String awardLevel;

        // getters and setters
        public Integer getUserId() { return userId; }
        public void setUserId(Integer userId) { this.userId = userId; }
        public Integer getPrizeId() { return prizeId; }
        public void setPrizeId(Integer prizeId) { this.prizeId = prizeId; }
        public Integer getSettingId() { return settingId; }
        public void setSettingId(Integer settingId) { this.settingId = settingId; }
        public String getAwardLevel() { return awardLevel; }
        public void setAwardLevel(String awardLevel) { this.awardLevel = awardLevel; }
    }

    /**
     * 设置请求参数
     */
    public static class LotterySettingsRequest {
        private LotteryPrize prize;
        private List<LotterySetting> settings;

        // getters and setters
        public LotteryPrize getPrize() { return prize; }
        public void setPrize(LotteryPrize prize) { this.prize = prize; }
        public List<LotterySetting> getSettings() { return settings; }
        public void setSettings(List<LotterySetting> settings) { this.settings = settings; }
    }

    /**
     * 开始抽奖请求参数
     */
    public static class LotteryStartRequest {
        private Integer userId;
        private Integer settingId;

        // getters and setters
        public Integer getUserId() { return userId; }
        public void setUserId(Integer userId) { this.userId = userId; }
        public Integer getSettingId() { return settingId; }
        public void setSettingId(Integer settingId) { this.settingId = settingId; }
    }
} 